package com.influency.itlab.http.base;

import android.util.Log;


import com.influency.itlab.BuildConfig;
import com.influency.itlab.http.convert.CustomGsonConverterFactory;

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;

public class RetrofitManager {
    String TAG = RetrofitManager.class.getSimpleName();
    private static volatile RetrofitManager instance;

    private RetrofitManager() {
        getNetClient();
    }

    public static RetrofitManager getInstance() {
        if(instance == null){
            //double check lock :DCL
            synchronized (RetrofitManager.class) {
                if (instance == null) {
                    synchronized (RetrofitManager.class) {
                        instance = new RetrofitManager();
                    }
                }
            }
        }
        return instance;
    }

    public <T> T create(Class<T> service){
        return mRetrofitInstance.create(service);
    }
    private Retrofit mRetrofitInstance;
    private OkHttpClient okClient;

    private void getNetClient() {
        if(mRetrofitInstance == null){
             okClient = new OkHttpClient().newBuilder()
                    .sslSocketFactory(getSslContext(trustManager).getSocketFactory(), trustManager)
                    .addInterceptor(mResponseInterceptor)
                    .retryOnConnectionFailure(true)
                    .connectTimeout(10, TimeUnit.SECONDS)
                    .writeTimeout(30, TimeUnit.SECONDS)
                    .readTimeout(30, TimeUnit.SECONDS)
                    .build();
            mRetrofitInstance = new Retrofit.Builder()
                    .client(okClient)
                    .baseUrl(ApiMap.BASE_URL)
                    .addConverterFactory(CustomGsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava3CallAdapterFactory.createSynchronous())
                    .build();
        }
    }


//    public void enqueue(Request request,SyncCallback callback){
//        getNetClient().newCall(request).enqueue(callback);
//    }


    private X509TrustManager trustManager = new X509TrustManager() {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {

        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    };

    private SSLContext getSslContext(X509TrustManager trustManager) {
        SSLContext sslContext = null;
        try {
            sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, new TrustManager[]{trustManager}, new SecureRandom());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        return sslContext;
    }

    private Interceptor mBaiduAkInterceptor = new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request original = chain.request();
            HttpUrl originalHttpUrl = original.url();

            HttpUrl.Builder urlBuilder = originalHttpUrl.newBuilder();

            if (!originalHttpUrl.queryParameterNames().contains("ak")) {
                urlBuilder.addQueryParameter("ak", "987654321");
            }


            // Request customization: onChecked request headers
            Request.Builder requestBuilder = original.newBuilder()
                    .url(urlBuilder.build());

            Request request = requestBuilder.build();
            return chain.proceed(request);
        }
    };
    private Interceptor mResponseInterceptor = new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request.Builder requestBuilder = chain.request().newBuilder()
                    .addHeader("Content-Type", "application/json; charset=UTF-8")
//                                .addHeader("Accept-Encoding", "gzip")
                    .addHeader("Connection", "Keep-Alive")
                    .addHeader("Accept", "*/*")
                    .addHeader("Charset", "UTF-8");
            if (BuildConfig.DEBUG) {
//                requestBuilder.addHeader("token", "eyJ1c2VyVHlwZSI6MTAsImFsZyI6IkhTMjU2In0.eyJwYXNzZW5nZXIiOiJ7XCJwYXNzZW5nZXJJZFwiOlwiYjdkNmE4YzktM2Q0MC00NDAwLTgyZmUtODg0NjE4YWQ1YjFjXCJ9IiwiZXhwIjoxNjE4Mzc4NTI0LCJpYXQiOjE2MTc3NzM3MjR9.cpeOq4--FeUI77oJ9thNzgqryQms28k8s51nwuPSNqI");
//                requestBuilder.addHeader("token", "eyJ1c2VyVHlwZSI6MzAsImFsZyI6IkhTMjU2In0.eyJleHAiOjE2MTc4MDM0ODEsInVzZXIiOiJ7XCJpZFwiOjIyNixcImlkTmFtZVwiOlwi6Im-546J6aOeKDIyNilcIixcIm5hbWVcIjpcIuiJvueOiemjnlwiLFwib3JnSWRcIjoxfSIsImlhdCI6MTYxNzc3NDY4MX0.-sRLQnPKeK_ULxMci-y27J9ItSEb5nXsA8kqIUYqzVg");
            }
            Response originResponse = chain.proceed(requestBuilder.build());
            String content = "";
            MediaType mediaType = null;
            String protocol = originResponse.protocol().name();
            int httpStatusCode = originResponse.code();
            if (originResponse.isSuccessful()) {
                ResponseBody responseBody = originResponse.body();
                if (responseBody != null) {
                    content = responseBody.string();
                    mediaType = responseBody.contentType();//获取返回结果的type
                }
            }
            StringBuffer logBuffer = new StringBuffer();
            logBuffer.append("protocol = "+protocol+", ");
            logBuffer.append("httpStatusCode = "+httpStatusCode+", ");
            logBuffer.append("content = "+content);
            Log.e(TAG, "--response:" + logBuffer);
            return originResponse.newBuilder().body(ResponseBody.create(mediaType, content)).build();
        }
    };
}
